<?php


namespace app\services\order;


use app\common\OrderStatus;
use app\models\coupon\CouponModel;
use app\models\coupon\UserCouponModel;
use app\models\order\OrderDetailModel;
use app\models\order\OrderModel;
use app\models\user\UserModel;
use app\services\config\ConfigService;
use app\services\user\DetailedGreenScoresService;
use Overtrue\Socialite\User;
use think\Exception;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Log;


class OrderService
{
    private static $orderStatus = [
//        0 => '已取消',
//        1 => '待付款',
//        2 => '待领取',
//        3 => '已完成',

        '0' => '已取消',
        '1' => '待付款',
        '2' => '待发货',
        '3' => '待收货',
        '4' => '待评价',
        '5' => '已完成',
        '6' => '已退单',
        '7' => '待售后',
        '8' => '已处理',
    ];

    public static function getOrderStatusAttr($orderStatus)
    {
        return self::$orderStatus[$orderStatus];
    }

    public static function getOrderStatusArr()
    {
        return self::$orderStatus;
    }

    /**
     * 支付完成后
     * @param $order_sn
     * @return true
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function handleOrder($order_sn){
        $order = OrderModel::where('order_sn',$order_sn)->find();
        $order->order_status = 2;//更新订单状态
        $order->pay_time = time();
        $order->save();

        //商品销量增加

        return true;
    }

    /**
     * 订单确认收货后
     * @return void
     */
    public static function completeOrder($order_sn)
    {
        $order = OrderModel::where('order_sn',$order_sn)->find();
        $user =  UserModel::where('id',$order->user_id)->find();

        //达到人数要求,赠送绿色积分
        $type = DetailedGreenScoresService::ORDER;
        DetailedGreenScoresService::create($order->user_id,$type,$order->green_scores,$order_sn);

        $user->effective_purchase += 1;
        if($user->label == 0){
            $user->label = $order->label;
        }
        if($user->first_label == 0){
            $user->first_label = $order->label;
        }
        $user->save();

        //第一次购买商品,并且购买的是征信商品,向邀请人送积分
        if($user->effective_purchase == 1 && $user->label == 1 && $user->inviter != 0){
            $inviter = UserModel::where('id',$user->inviter)->find();
            if($inviter){
                $config = ConfigService::getConfigValue('good_credit_reporting');
                $config = $config[0];
                $green_scores = isset($config['green_scores']) ? $config['green_scores'] : 0;
                $count = UserModel::where('first_label',1)->where('inviter',$user->inviter)->count();
                if($count > $config['num']){
                    //达到人数要求,赠送绿色积分
                    $type = DetailedGreenScoresService::REWARD;
                    DetailedGreenScoresService::create($user->inviter,$type,$green_scores,$order_sn);
                }
            }
        }

        //商品销量增加
        $order_detail = OrderDetailModel::where('order_sn',$order_sn)->field('goods_id,num')->select();
        foreach($order_detail as $item){
            Db::name('goods')->where('id',$item['goods_id'])->inc('sales',1)->update();
        }

        return true;
    }

    /**
     * 订单确认
     * @param $orderSn
     * @return bool
     * @throws \Exception
     */
    public function confirmOrder($orderSn)
    {
        $key = 'order:confirm:' . $orderSn;
        try {
            if (Cache::get($key)) {
                throw new \Exception('请勿频繁点击');
            }
            Cache::set($key, time(), 10);
            $orderInfo = Db::name('order')->where('order_sn', $orderSn)->find();
            if (!$orderInfo) {
                throw new \Exception("订单号错误");
            }
            if ($orderInfo['order_status'] != 2) {
                throw new \Exception("订单状态错误");
            }
            $buyUserId = $orderInfo['buy_user_id'];
            $buyUserInfo = Db::name('user')->where('id', $buyUserId)->lock(true)->find();
            if (!$buyUserInfo) {
                throw new \Exception("买家不存在");
            }
            // 卖方订单更新为已出
            Db::name('order')->where('order_sn', $orderSn)->update([
                'order_status' => OrderStatus::WAIT_ONLINE,
                'confirm_time' => time(),
                'update_time' => date('Y-m-d H:i:s'),
            ]);
            // 买方获得上架费
//            Db::name('user')->where('id', $buyUserId)->inc("score", $orderInfo['online_price'])->update();
//            Db::name('detailed_score')->insert([
//                'user_id' => $buyUserId,
//                'user_name' => $buyUserInfo['user_name'],
//                'money' => $orderInfo['online_price'],
//                'balance' => $buyUserInfo['score'],
//                'relevant_user_id' => $orderInfo['user_id'],
//                'relevant_name' => '',
//                'order_sn' => $orderSn,
//                'create_time' => date('Y-m-d H:i:s'),
//                'remark' => '上架费'
//            ]);
            // 买方的直属上级拿0.5%的佣金
//            if ($buyUserInfo['inviter']) {
//                $inviteUserId = $buyUserInfo['inviter'];
//                $inviteUserInfo = Db::name('user')->where('id', $inviteUserId)->lock(true)->find();
//                if ($inviteUserInfo) {
//                    $money = number_format($orderInfo['price'] * 0.005, 2);
//                    Db::name('user')->where('id', $inviteUserId)->inc("money", $money)->update();
//                    Db::name('detailed_money')->insert([
//                        'user_id' => $inviteUserId,
//                        'user_name' => $inviteUserInfo['user_name'],
//                        'user_mobile' => $inviteUserInfo['mobile'],
//                        'money' => $money,
//                        'balance' => $inviteUserInfo['money'],
//                        'relevant_user_id' => $buyUserId,
//                        'relevant_name' => $buyUserInfo['user_name'],
//                        'order_sn' => $orderSn,
//                        'create_time' => date('Y-m-d H:i:s'),
//                        'remark' => '直推业绩奖励'
//                    ]);
//                }
//            }
            // 购买价格
            $price = $orderInfo['pay_price'];
            // 该订单的上架费
//            $onlinePrice = bcmul($price, 0.025, 2);

//            $total = bcadd($price, $onlinePrice, 2);
            // 利润
//            $total2 = bcmul($total, 0.015, 2);
//            $payPrice1 = bcadd($price, $onlinePrice, 2);
            // 卖出的价格
//            $payPrice = bcmul($price, 1.04, 2);
//            $newOrderSn = createOrderSn();
            // 为指派人生成新订单
//            Db::name('order')->insert([
//                'paint_id' => $orderInfo['paint_id'],
//                'user_id' => $buyUserId,
//                'sell_user_id' => $orderInfo['user_id'],
//                'goods_id' => $orderInfo['goods_id'],
//                'price' => $price,
//                'online_price' => $onlinePrice,
//                'pay_price' => $payPrice,
//                'order_sn' => $newOrderSn,
//                'old_order_sn' => $orderSn,
//                'order_status' => OrderStatus::WAIT_ONLINE,
//                'create_time' => date('Y-m-d H:i:s'),
//                'update_time' => date('Y-m-d H:i:s'),
//            ]);
            // 更新盲盒的归属
            Db::name('goods')->where('id', $orderInfo['goods_id'])->update([
                'user_id' => $buyUserId,
                'price' => $price,
                'update_time' => time(),
            ]);
            return true;
        } catch (\Exception $exception) {
            Log::error("订单{$orderSn}确认失败:" . $exception->getMessage());
            Cache::delete($key);
            throw new \Exception($exception->getMessage());
        }
    }

    /**
     * 指派订单
     * @param $inviteCode
     * @param $goodsId
     * @return bool
     * @throws \Exception
     */
    public function appointOrder($inviteCode, $goodsId)
    {
        $key = 'order:appoint:' . $goodsId . ":" . $inviteCode;
        try {
            if (Cache::get($key)) {
                throw new \Exception('请勿频繁指派');
            }
            Cache::set($key, time(), 5);
            $userInfo = Db::name('user')->where('invite_code', $inviteCode)->find();
            if (!$userInfo) {
                throw new \Exception('指派人不存在');
            }
            $paymentInfo = Db::name('user_payment')->where('customer_id', $userInfo['id'])->find();
            if (!$paymentInfo) {
                throw new \Exception('指派人尚未上传收款方式');
            }
            $appointUid = $userInfo['id'];
            $goodsInfo = Db::name('goods')->where('id', $goodsId)->where('status', 1)->find();
            if (!$goodsInfo) {
                throw new \Exception("商品不存在或已封存");
            }
            if ($goodsInfo['user_id'] == $appointUid) {
                throw new \Exception("盲盒已已经属于指派人");
            }
            // 生成订单
            $price = $goodsInfo['price'];
            $onlinePrice = bcmul($price, 0.025, 2);
            $payPrice = bcmul($price, 1.04, 2);
            $newOrderSn = createOrderSn();
            Db::name('order')->insert([
                'user_id' => $goodsInfo['user_id'],
                'buy_user_id' => $appointUid,
                'goods_id' => $goodsId,
                'price' => $goodsInfo['price'],
                'online_price' => $onlinePrice,
                'pay_price' => $payPrice,
                'order_sn' => $newOrderSn,
                'old_order_sn' => '',
                'order_status' => OrderStatus::WAIT_PAY,
                'is_apply_online' => 1,
                'paint_id' => $goodsInfo['paint_id'],
                'apply_online_time' => date('Y-m-d H:i:s'),
                'create_time' => date('Y-m-d H:i:s'),
                'update_time' => date('Y-m-d H:i:s'),
            ]);
            Db::name('goods')->where('id', $goodsId)->update([
                'is_appoint' => 1,
                'update_time' => time()
            ]);
            return true;
        } catch (\Exception $exception) {
            Log::error("订单{$goodsId}-{$inviteCode}指派失败:" . $exception->getMessage());
            throw new \Exception($exception->getMessage());
        }
    }

    /**
     * 我已付款
     * @param $orderSn
     * @return bool
     * @throws \Exception
     */
    public function hasPayOrder($orderSn)
    {
        try {
            $orderInfo = Db::name('order')->where('order_sn', $orderSn)->find();
            if (!$orderInfo) {
                throw new \Exception("订单号错误");
            }
            Db::name('order')->where('order_sn', $orderSn)->update([
                'order_status' => OrderStatus::WAIT_PAYEE,
                'pay_time' => time(),
                'update_time' => getFormatDate()
            ]);
            return true;
        } catch (\Exception $exception) {
            Log::error("订单{$orderSn}支付失败:" . $exception->getMessage());
            throw new \Exception($exception->getMessage());
        }
    }


    /**
     * 优惠券是否可用
     * @param $userCouponId
     * @param $totalAmount
     * @param $goodsId
     * @return mixed
     * @throws \Exception
     */
    public static function checkUserCoupon($userCouponId, $totalAmount, $goodsId)
    {
        try {
            if (!$userCouponId) {
                return 0;
            }
            $userCouponInfo = UserCouponModel::find($userCouponId);
            if (!$userCouponInfo) {
                throw new \Exception('用户没有该优惠券');
            }
            if ($userCouponInfo['status'] != 0) {
                throw new \Exception('优惠券已删除');
            }
            if ($userCouponInfo['is_used'] != 0) {
                throw new \Exception('优惠券已使用');
            }
            $currentTime = time();
            if ($currentTime < $userCouponInfo['use_start_time']) {
                throw new \Exception('优惠券未到使用时间');
            }
            if ($currentTime > $userCouponInfo['use_end_time']) {
                throw new \Exception('优惠券已过期');
            }
            if ($totalAmount < $userCouponInfo['less_amount']) {
                throw new \Exception("优惠券满{$userCouponInfo['less_amount']}元可用");
            }
            $typeIdArr = json_decode($userCouponInfo['type_id'],true);
            if ($userCouponInfo['use_type'] == 1 && !in_array($goodsId, $typeIdArr)) {
                throw new \Exception("当前服务不可用");
            }
            if ($userCouponInfo['use_type'] == 2 && in_array($goodsId, $typeIdArr)) {
                throw new \Exception("当前服务不可用");
            }
            if($userCouponInfo['coupon_type'] == 0){
                return $userCouponInfo['amount'];
            }elseif ($userCouponInfo['coupon_type'] == 1){
                return $totalAmount - bcmul($totalAmount,$userCouponInfo['amount'] / 10,2);
            }else{
                return $totalAmount;
            }

        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }

    /**
     * 返回支付方式和金额
     * @return void
     */
    public static function payType($money,$green_scores = 0,$userId = 0)
    {
        $pay_data = [
            'ali_pay' => ConfigService::getConfigValue('ali_pay'),
            'wx_pay' => ConfigService::getConfigValue('wx_pay'),
            'balance_pay' => ConfigService::getConfigValue('balance_pay'),
            'balance_plus_points_pay' => ConfigService::getConfigValue('balance_plus_points_pay'),
            'green_scores' => $green_scores,
            'user_integral' => UserModel::where('id',$userId)->value('integral'),
            'user_money' => UserModel::where('id',$userId)->value('money'),
        ];

        //积分支付占比
        $points_pay_proportion = ConfigService::getConfigValue('points_pay_proportion');
        if($pay_data['balance_plus_points_pay'] == 1){
            //获取需要积分支付数量 金额除以100,乘以兑换比例
            $integral = bcmul(bcdiv($money,100,3),(float)$points_pay_proportion,2);
            //积分兑换余额比例
            $point_redemption_ratio = ConfigService::getConfigValue('point_redemption_ratio');
            $order_integral = bcmul(bcdiv($integral,100,3),$point_redemption_ratio,2);
        }else{
            $order_integral = 0;
        }

        $pay_data['order_integral'] = $order_integral;
        $pay_data['order_balance'] =  bcsub($money,$order_integral,2);

        return $pay_data;
    }
}